package com.lxd.sunso.product.netty.server.socket;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lxd.sunso.product.entity.*;
import com.lxd.sunso.product.netty.domain.Device;
import com.lxd.sunso.product.netty.util.CacheUtil;
import com.lxd.sunso.product.service.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Collection;


import static com.lxd.sunso.product.netty.util.CacheUtil.deviceGroup;


@Component
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    private static final Logger logger = LoggerFactory.getLogger("newLogger");

    public static NettyServerHandler nettyServerHandler;

    @Autowired
    private MachineService machineService;

    @Autowired
    private NettyService nettyService;

    public NettyServerHandler() {
    }

    @PostConstruct
    public void init() {
        nettyServerHandler = this;
        nettyServerHandler.machineService = this.machineService;
        nettyServerHandler.nettyService = this.nettyService;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            //将msg转为一个ByteBuf,与NIO中的ByteBuffer存在一定的差别
            ByteBuf buf = (ByteBuf) msg;
            nettyServerHandler.nettyService.parseDataFromLow(ByteBufUtil.hexDump(buf), ctx);
            //nettyServerHandler.nettyService.testDataFromLow(ByteBufUtil.hexDump(buf), ctx);
            ctx.flush();
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

    /**
     * 当客户端主动断开服务端的链接后，这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        String channelId = ctx.channel().id().toString();
        //修改设备的在线状态
        machineOut(channelId);
        //移除设备信息
        deviceGroup.remove(channelId);
        CacheUtil.cacheClientChannel.remove(channelId);
    }

    //异常的处理，一般是需要关闭通道
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //System.out.println(cause.getMessage());
        logger.info((cause.getMessage()));
        ctx.close();
     /*   String channelId = ctx.channel().id().toString();
        //修改设备的在线状态
        machineOut(channelId);
        //移除设备信息
        deviceGroup.remove(channelId);
        CacheUtil.cacheClientChannel.remove(channelId);*/
    }


    //监听到设备下线时，修改设备的在线状态为0
    public void machineOut(String channelId) {
        String machineName = null;
        Collection<Device> deviceInfos = CacheUtil.deviceGroup.values();
        for (Device device : deviceInfos) {
            if (device.getChannelId().equals(channelId)) {
                machineName = device.getMachineName();
            }
        }
        MachineEntity entity = nettyServerHandler.machineService.getOne(new QueryWrapper<MachineEntity>().eq("MachineName", machineName));
        entity.setIsonline("0");
        nettyServerHandler.machineService.updateById(entity);
        logger.info("设备：" + machineName + "下线");
    }
}
